# encoding: utf-8
# Author    : limusen
# Datetime  : 2021/12/8 8:42 下午


import re
import json
from nb_log import LogManager
from common.config_utils import local_config
from common.logs_utils import logger
from common.mysql_utils import mysql_result


class CheckUtils:

    def __init__(self, response_data):
        self.response_data = response_data
        self.function = {
            "none": self.__none_check,
            "json_key": self.__key_check,
            "json_key_value": self.__key_value_check,
            "body_regexp": self.__body_regexp_check,
            "header_key_check": self.__header_key_check,
            "header_key_value_check": self.__header_key_value_check,
            "response_code_check": self.__response_code_check,
            "mysql_key": self.__mysql_check,
            "contain_text": self.__contain_text

        }
        self.pass_result = {  # 通过结果
            "code": 0,
            "response_code": self.response_data.status_code,
            "response_reason": self.response_data.reason,
            "response_headers": self.response_data.headers,
            "response_body": self.response_data.text,
            "message": "测试用例执行通过",
            "check_result": True
        }
        self.fail_result = {  # 失败结果 2 表示断言失败
            "code": 2,
            "response_code": self.response_data.status_code,
            "response_reason": self.response_data.reason,
            "response_headers": self.response_data.headers,
            "response_body": self.response_data.text,
            "message": "测试用例断言失败，测试用例执行不通过",
            "check_result": False
        }

    def __none_check(self):
        """
        检查是否为空
        :return:
        """
        logger.info("断言类型 [none],不进行断言，本次断言通过")
        return self.pass_result

    def __key_check(self, check_data):
        """
        检查json断言 检查键断言
        :param check_data:
        :return:
        """
        key_list = check_data.split(",")
        tmp_result = []

        for check_key in key_list:
            if check_key in self.response_data.json().keys():
                tmp_result.append(True)
            else:
                tmp_result.append(False)
        if False in tmp_result:
            logger.error('断言类型 [key_check] ==》实际结果：{}, 期望结果：{} 不相符，断言失败'.format(self.response_data.text, check_data
                                                                                ))
            return self.fail_result
        else:
            logger.info("断言类型 [key_check],检查键值，实际结果：{}, 期望结果：{} 相符，断言成功".format(self.response_data.text, check_data
                                                                                ))
            return self.pass_result

    def __key_value_check(self, check_data):
        """
        检查键跟值是否一致
        :param check_data:
        :return:
        """
        key_value_dict = json.loads(check_data)
        tmp_result = []

        for key_value in key_value_dict.items():
            if key_value in self.response_data.json().items():
                tmp_result.append(True)
            else:
                tmp_result.append(False)
        if False in tmp_result:
            logger.error(
                '断言类型 [key_value_check] ==》实际结果：{}, 期望结果：{} 不相符，断言失败'.format(self.response_data.text, check_data
                                                                             ))
            return self.fail_result
        else:
            logger.info('断言类型 [key_value_check] ==》实际结果：{}, 期望结果：{} 相符，断言成功'.format(self.response_data.text, check_data
                                                                                    ))
            return self.pass_result

    def __body_regexp_check(self, check_data):
        """
        正则表达式断言
        :param check_data:
        :return:
        """
        if re.findall(check_data, self.response_data.text):
            logger.info(
                '断言类型 [body_regexp_check] ==》实际结果：{}, 期望结果：{} 相符，断言成功'.format(self.response_data.text, check_data
                                                                              ))
            return self.pass_result
        else:
            logger.error(
                '断言类型 [body_regexp_check] ==》实际结果：{}, 期望结果：{} 不相符，断言失败'.format(self.response_data.text, check_data
                                                                               ))
            return self.fail_result

    def __header_key_check(self, check_data):
        """
        检查头部
        :param check_data:
        :return:
        """
        key_list = check_data.split(",")
        tmp_result = []

        for check_key in key_list:
            if check_key in self.response_data.headers.keys():
                tmp_result.append(True)
            else:
                tmp_result.append(False)
        if False in tmp_result:
            logger.error(
                '断言类型 [header_key_check] ==》实际结果：{}, 期望结果：{} 不相符，断言失败'.format(self.response_data.text, check_data
                                                                              ))
            return self.fail_result
        else:
            logger.info(
                '断言类型 [header_key_check] ==》实际结果：{}, 期望结果：{} 相符，断言成功'.format(self.response_data.text, check_data
                                                                             ))
            return self.pass_result

    def __header_key_value_check(self, check_data):
        """
        检查键跟值是否一致
        :param check_data:
        :return:
        """
        key_value_dict = json.loads(check_data)
        tmp_result = []

        for key_value in key_value_dict.items():
            if key_value in self.response_data.headers.items():
                tmp_result.append(True)
            else:
                tmp_result.append(False)
        if False in tmp_result:
            logger.error(
                '断言类型 [header_key_value_check] ==》实际结果：{}, 期望结果：{} 不相符，断言失败'.format(self.response_data.text, check_data
                                                                                    ))
            return self.fail_result
        else:
            logger.info(
                '断言类型 [header_key_value_check] ==》实际结果：{}, 期望结果：{} 相符，断言成功'.format(self.response_data.text, check_data
                                                                                   ))
            return self.pass_result

    def __response_code_check(self, check_data):
        """
        检查返回状态码
        :param check_data:
        :return:
        """
        if self.response_data.status_code == int(check_data):
            logger.info(
                '断言类型 [__response_code_check] ==》实际结果：{}, 期望结果：{} 相符，断言成功'.format(self.response_data.text, check_data
                                                                                  ))
            return self.pass_result
        else:
            logger.error(
                '断言类型 [__response_code_check] ==》实际结果：{}, 期望结果：{} 不相符，断言失败'.format(self.response_data.text, check_data
                                                                                   ))
            return self.fail_result

    def __mysql_check(self, check_data):
        """
        数据断言
        :param check_data:
        :return:
        """

        if mysql_result.get_sql_all(check_data):
            logger.info(
                '断言类型 [__mysql_check] ==》实际结果：{}, 期望结果：{} 相符，断言成功'.format(self.response_data.text, check_data
                                                                          ))
            return self.pass_result
        else:
            logger.error(
                '断言类型 [__mysql_check] ==》实际结果：{}, 期望结果：{} 不相符，断言失败'.format(self.response_data.text, check_data
                                                                           ))
            return self.fail_result

    def __contain_text(self, check_data):
        """
        断言数据中是否存在该字段
        :param check_data:
        :return:
        """
        if check_data in self.response_data.text:
            logger.info(
                '断言类型 [__contain_text] ==》实际结果：{}, 期望结果：{} 相符，断言成功'.format(self.response_data.text, check_data
                                                                          ))
            return self.pass_result
        else:
            logger.error(
                '断言类型 [__contain_text] ==》实际结果：{}, 期望结果：{} 不相符，断言失败'.format(self.response_data.text, check_data
                                                                           ))
            return self.fail_result


    def run_check(self, check_type, excepted_result):
        """
        断言运行总入口
        :param check_type:
        :param excepted_result:
        :return:
        """
        logger.info("根据断言类型[%s]断言。检查是否满足期望结果[%s]" % (check_type, excepted_result))
        try:
            if check_type == "none" or excepted_result == "":
                # 当断言类型为none 或者 期望结果为空  都统一调用不检查
                return self.function["none"]()
        except Exception as e:
            logger.error(e.__str__())
        return self.function[check_type](excepted_result)


if __name__ == '__main__':
    import requests

    url = "http://8.136.151.26:8012/live/video/detail"
    header = {
        "Authorization": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ7XCJpZFwiOjEwNTQ5LFwidXNlck5hbWVcIjpcIllXTDgxNjQwMDU5MzI3MjA5MTQ0MzJcIixcInVzZXJQaG9uZVwiOlwiMTU1NzQ4NjYzNjlcIixcInVzZXJHZW5lcmF0ZUNvZGVcIjo4MTY0MDA1OTMyNzIwOTE0NDMyLFwicG9ydHJhaXRVcmxcIjpudWxsLFwiaWRlbnRpdHlcIjpcIk5vcm1hbFwiLFwibGFzdExvZ2luVGltZVwiOm51bGwsXCJyb2xlSWRcIjoyLFwiYWN0aXZhdGlvblwiOmZhbHNlfSIsInJvbGVJZCI6MiwiaXNzIjoidmFsaWQiLCJleHAiOjE2NDMyNTI5MDcsInVzZXJJZCI6ODE2NDAwNTkzMjcyMDkxNDQzMiwiaWF0IjoxNjQwNj"
                         "YwOTA3LCJqdGkiOiI4MTY0MDA1OTMyNzIwOTE0NDMyIn0.KomPubk7Do8jIFcdvDpYN0ETOoiP0pSiv4Hx-qa6dgI"
    }
    get_params = {"grant_type": "client_credential", "appid": "wxb637f897f0bf1f0d",
                  "secret": "501123d2d367b109a5cb9a9011d0f084"}
    json_params = {"id": "2021101400000002"}

    response = requests.post(url=url, json=json_params, headers=header)
    print(response.text)
    ck = CheckUtils(response)

    print(ck.run_check("contain_text", "approvalStatus"))
